/* Copyright (c) 2024 Qualcomm Technologies International, Ltd. */
/* %%version */

#include "gatt_ots_client_read_object_metadata.h"
#include "gatt_ots_client_common_util.h"

/*******************************************************************************
* API to read object's metadata from the OTS server.
*******************************************************************************/
bool GattOtscReadObjectMetadataReq(ServiceHandle svcHandle,
                                   GattOtscCharacteristicsId characId)
{
    GOTSC *gattOtsClient = ServiceHandleGetInstanceData(svcHandle);

    GATT_OTS_CLIENT_INFO("GOTSC: GattOtscReadObjectMetadataReq: svcHandle[%0x] CharacId[%04x]\n", svcHandle, characId);

    if (gattOtsClient)
    {
        OtscInternalMsgReadObjectMetadata *message = CsrPmemZalloc(sizeof(*message));

        message->svcHandle = svcHandle;
        message->characId  = characId;

        GattOtscMessageSend(gattOtsClient->libTask,
                            OTSC_INTERNAL_MSG_READ_OBJ_METADATA_REQ,
                            message);
        return (TRUE);
    }
    else
    {
        GATT_OTS_CLIENT_ERROR("GOTSC: No OTS Client instance found!\n");
        return (FALSE);
    }
}

void OtscSendReadObjectMetadataCfm(GOTSC *const              gattOtsClient,
                                   GattOtscCharacteristicsId characId,
                                   uint16                    valueLen,
                                   uint8                    *value,
                                   CsrBtResultCode           result,
                                   CsrBtSupplier             supplier)
{
    GattOtscReadObjectMetadataCfm *message = CsrPmemZalloc(sizeof(*message));

    if (valueLen)
    {
        message->value = CsrPmemZalloc(valueLen);
    }

    message->svcHandle  = gattOtsClient->srvcElem->service_handle;
    message->characId   = characId;
    message->valueLen   = valueLen;
    CsrMemCpy(message->value, value, valueLen);
    message->resultCode = result;
    message->supplier   = supplier;

    GATT_OTS_CLIENT_INFO("GOTSC: OtscSendReadObjectMetadataCfm: svcHandle[%0x]\n", gattOtsClient->srvcElem->service_handle);

    /* Send the confirmation message to app task  */
    GattOtscMessageSend(gattOtsClient->appTask,
                        GATT_OTSC_READ_OBJECT_METADATA_CFM,
                        message);
}

void OtscHandleInternalMsgReadObjectMetadata(GOTSC *const gattOtsClient,
                                             OtscInternalMsgReadObjectMetadata *msg)
{
    GATT_OTS_CLIENT_INFO("GOTSC: OtscHandleInternalMsgReadObjectMetadata: svcHandle[%0x]\n", gattOtsClient->srvcElem->service_handle);

    if (gattOtsClient->pendingCmd & OTSC_PENDING_OP_READ_CHARS_FOR_OBJ_CONTENT)
    {
        OtscSendReadObjectMetadataCfm(gattOtsClient, msg->characId,
                                      0, NULL,
                                      GATT_OTSC_RESULT_CODE_BUSY,
                                      GATT_SUPPLIER_OTS_CLIENT);
        GATT_OTS_CLIENT_ERROR("GOTSC: Read object metadata failed!\n");
    }
    else
    {
        ServiceHandle handle = GattOtscGetCharacHandleForCharacId(gattOtsClient,
                                                                  msg->characId);

        if (handle != INVALID_PROFILE_HANDLE)
        {
            CsrBtGattReadReqSend(gattOtsClient->srvcElem->gattId,
                                 gattOtsClient->srvcElem->cid,
                                 handle,
                                 0);
        }
        else
        {
            OtscSendReadObjectMetadataCfm(gattOtsClient, msg->characId,
                                          0, NULL,
                                          GATT_OTSC_RESULT_CODE_INVALID_PARAMETER,
                                          GATT_SUPPLIER_OTS_CLIENT);
        }
    }
}

void OtscHandleReadCfmToReadObjectMetadata(GOTSC *const gattOtsClient,
                                           const CsrBtGattReadCfm *cfm)
{
    GattOtscCharacteristicsId characId = GattOtscGetCharacIdForCharacHandle(gattOtsClient,
                                                                   cfm->handle);

    if (cfm->resultCode == CSR_BT_GATT_RESULT_SUCCESS)
    {
        if (characId != GATT_OTSC_CHARAC_ID_NONE)
        {
            OtscSendReadObjectMetadataCfm(gattOtsClient, characId,
                                          cfm->valueLength, cfm->value,
                                          GATT_OTSC_RESULT_CODE_SUCCESS,
                                          GATT_SUPPLIER_OTS_CLIENT);

            if (characId == GATT_OTSC_CHARAC_ID_OBJ_LIST_FILTER)
            {
                CsrBtGattHandle handle = INVALID_PROFILE_HANDLE;

                /* Make sure we read all of the filter characteristics value */
                if (cfm->handle == gattOtsClient->deviceData.objListFilterHandle1)
                {
                    if (gattOtsClient->deviceData.objListFilterHandle2)
                    {
                        handle = gattOtsClient->deviceData.objListFilterHandle2;
                    }
                }
                else if (cfm->handle == gattOtsClient->deviceData.objListFilterHandle2)
                {
                    if (gattOtsClient->deviceData.objListFilterHandle3)
                    {
                        handle = gattOtsClient->deviceData.objListFilterHandle3;
                    }
                }

                if (handle != INVALID_PROFILE_HANDLE)
                {
                    CsrBtGattReadReqSend(gattOtsClient->srvcElem->gattId,
                                         gattOtsClient->srvcElem->cid,
                                         handle,
                                         0);
                }
            }
        }
        else
        {
            OtscSendReadObjectMetadataCfm(gattOtsClient, characId,
                                          0, NULL,
                                          GATT_OTSC_RESULT_CODE_OPERATION_FAILED,
                                          GATT_SUPPLIER_OTS_CLIENT);
        }
    }
    else
    {
        OtscSendReadObjectMetadataCfm(gattOtsClient, characId,
                                      0, NULL,
                                      cfm->resultCode,
                                      cfm->resultSupplier);
    }
}

